﻿#region MyJScript - LGPL Copyright (c) 2008 Lionel Laské
//
// This file is part of MyJScript.
//
// MyJScript is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// MyJScript is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with MyJScript; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
//================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;

namespace MyJScript.Host
{
    /// <summary>
    /// Hosting DLR test
    /// </summary>
    class Program
    {
        /// <summary>
        /// Entry point
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Create runtime
            ScriptRuntime runtime = ScriptRuntime.Create();

            // Preload System assembly
            runtime.LoadAssembly(typeof(string).Assembly);

            // Create a scope at global level
            ScriptScope globals = runtime.CreateScope();

            // Load MyJScript Engine
            ScriptEngine myjscript = runtime.GetEngine(typeof(MyJScript.DLR.MJSLanguageContext));

            // Load Python Engine
            ScriptEngine python = runtime.GetEngine(typeof(IronPython.Runtime.PythonContext));

            // Set Current language
            ScriptEngine current = myjscript;
            string command;

            // Interactive command line
            while (true)
            {
                // Write prompt
                Console.Write(current == myjscript ? "mjs>> " : "ipy>> ");
                command = ReadCommand();

                // Exit
                string lowercommand = command.ToLower();
                if (lowercommand.Equals("exit"))
                    break;
                
                // Change language
                else if (lowercommand.Equals("mjs"))
                {
                    current = myjscript;
                    continue;
                }
                else if (lowercommand.Equals("ipy"))
                {
                    current = python;
                    continue;
                }

                // Run
                RunProgram(current, command, globals);
            }
        }

        /// <summary>
        /// Run a command on a DLR engine.
        /// </summary>
        /// <param name="engine">engine to use</param>
        /// <param name="command">command to run</param>
        /// <param name="globals">global scope</param>
        static private void RunProgram(ScriptEngine engine, string command, ScriptScope globals)
        {
            ScriptSource src = engine.CreateScriptSourceFromString(command, SourceCodeKind.Statements);
            src.Execute(globals);
        }

        /// <summary>
        /// Read a multi-line command.
        /// </summary>
        /// <returns>the command</returns>
        static private string ReadCommand()
        {
            // Loop on each line
            StringBuilder command = new StringBuilder();
            while(true)
            {
                // Read a line
                string line = Console.ReadLine();
                command.Append(line);

                // Special command
                string value = command.ToString();
                if (value.Equals("exit") || value.Equals("mjs") || value.Equals("ipy"))
                    break;

                // Stop if end by ';' or '}'
                int length = line.Length;
                if (length == 0)
                    break;
                char lastchar = line[length - 1];
                if (lastchar == ';' || lastchar == '}')
                    break;

                // Wait for next line
                command.AppendLine();
                Console.Write("> ");
            }

            return command.ToString();
        }

    }
}
